import utility
import SecLogin
import MyOptionParser
import os, time, datetime, optparse, getpass
import socket
import threading
import SocketServer

path = '/tmp/test'
min_len = 6
max_len = 10
history_len = 4

sec_login = SecLogin.SecLogin(path, min_len, max_len, history_len)

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    
    def _parse_add(self, args):        
        if (sec_login == None):
            return 'Not initialized.'

        usage = "login [--user|-u] username"
        p = MyOptionParser.MyOptionParser(usage)

        p.add_option('--user', '-u', type="string", default = None)
        p.add_option('--pwd', '-p', type="string", default = None)        

        try:
            options, arguments = p.parse_args(args)
        except NameError:
            return 'Command parsing failed, not executed.'

        if (options.user == None):
            return 'Invalid username.'
        
        elif (options.pwd == None):
            return 'Invalid password.'
        
        #add user
        #return 'Got to adding user, %s %s' % (options.user, options.pwd)
        if ((sec_login.new_user(options.user, options.pwd)) == False):
            return 'Adding user failed.'
        return 'User successfuly added.'

    #login -u username
    def _parse_login(self, args):
        if (sec_login == None):
            return 'System uninitialized.'

        usage = "login [--user|-u] username [--pwd|-p] password"
        p = MyOptionParser.MyOptionParser(usage)

        p.add_option('--user', '-u', type="string", default = None)
        p.add_option('--pwd', '-p', type="string", default = None)        

        try:
            options, arguments = p.parse_args(args)
        except NameError:
            return 'Command parsing failed, not executed.'

        if (options.user == None):
            return 'Invalid username.'
        
        elif (options.pwd == None):
            return 'Invalid username.'

        else:
            if ((sec_login.login_user(options.user, options.pwd)) == False):
                return 'Login Failed.'
            else:
                return 'Login Successful.'

    def _parse_command(self, args):

        args = args.split()
        command = args[0]
        
        #Add a new user
        if command in ("add", "a"):            
            if (len(args) != 5):
                return 'Arguments missing for add command.'
            else:        
                return self._parse_add(args)

        #Login as a user
        elif command in ("login", "l"):
            if (len(args) != 5):
                return 'Arguments missing for login command.'
            else:        
                return self._parse_login(args)
        
        else:
            return 'Invalid command.'
    
    def handle(self):                
        data = self.request.recv(1024)
        cur_thread = threading.currentThread()
        response = self._parse_command(data)
        response = response + cur_thread.getName()
        self.request.send(response)

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    def shutdown(self):
        print 'Shutdown server.'
    #pass

def client(ip, port, message):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ip, port))
    sock.send(message)
    response = sock.recv(1024)
    print "Received: %s" % response
    sock.close()

if __name__ == "__main__":
    # Unit Test
    
    # Port 0 means to select an arbitrary unused port
    HOST, PORT = "localhost", 0

    server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
    ip, port = server.server_address

    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    # Exit the server thread when the main thread terminates
    server_thread.setDaemon(True)
    server_thread.start()
    print "Server loop running in thread:", server_thread.getName()

    client(ip, port, "add -u user1 -p password")
    client(ip, port, "add -u user2 -p password")
    client(ip, port, "add -u user3 -p password")

    client(ip, port, "login -u user1 -p PASSWORD")
    client(ip, port, "login -u user2 -p password")
    client(ip, port, "login -u user3 -p password")
    client(ip, port, "login -u user3 -p PASSWORD")

    server.shutdown()
